package com.budwk.app.sqfwDoc.codeGeneratorV2.capacity;

import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.AbstractCustomerPdfCreateField;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.PdfGenerateParam;
import com.budwk.app.sqfwDoc.codeGeneratorV2.generate.BasePdfGenerator;
import com.budwk.app.sqfwDoc.codeGeneratorV2.generate.ResultOfPdfGenerator;
import com.budwk.app.sqfwDoc.codeGeneratorV2.result.GeneratorPdfWordResult;
import com.budwk.app.util.ThreadLocalUtil;
import com.budwk.app.util.poiUtils.CommonPdfAndWordResult;
import com.google.common.collect.Lists;

import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Map;

import static com.budwk.app.util.poiUtils.CommonFormOfficeUtils.word2PdfAndUpload;

/**
 * @author ZY.Wang
 * @since 2024/1/24
 */
public abstract class AbstractCreatePdfCapacity implements IPdfCreateCapacity {

    @Override
    public GeneratorPdfWordResult generatePdf(PdfGenerateParam pdfGenerateParam) {
        GeneratorPdfWordResult result = new GeneratorPdfWordResult();
        ThreadLocalUtil.setUserId(pdfGenerateParam.getCreateUserCommonParam().getCreateUserId());
        // 用户自定义填充创建pdf所需参数
        customerPopularPdfGenerateParam(pdfGenerateParam);

        try {
            List<BasePdfGenerator> generatorList = getPdfGenerator(pdfGenerateParam);
            if (generatorList == null || generatorList.size() == 0) return result;

            List<ResultOfPdfGenerator> pdfResultList = Lists.newArrayList();
            for (BasePdfGenerator generator : generatorList) {
                ResultOfPdfGenerator pdfResult = generator.createPdf(pdfGenerateParam);

                if (pdfResult == null) continue;

                // 如果用户没有转为流则处理一下将XWPDf文件转为流
                if (!pdfResult.createOSFlag()) {
                    ByteArrayOutputStream pdfOs = new ByteArrayOutputStream();
                    pdfResult.getPdfXWPFTemplate().write(pdfOs);
                    pdfResult.setPdfOS(pdfOs);
                }

                // 允许用户可以在service层统一处理已经生成pdf
                getPdfGenerateResultAfter(pdfResult, generator);

                pdfResultList.add(pdfResult);
            }

            String fileName = getDownloadFileName(pdfGenerateParam);

            List<ByteArrayOutputStream> osList = Lists.newArrayList();
            for (ResultOfPdfGenerator resultOfPdfGenerator : pdfResultList) {
                if (resultOfPdfGenerator == null) continue;
                if (!resultOfPdfGenerator.getCreateSuccess()) continue;
                osList.add(resultOfPdfGenerator.getPdfOS());
            }

            // wzy 2024-3-18 如果一个pdf都没有的话，就不生成
            if (osList.size() == 0) return result;

            // 将生成的word文档合并为pdf并上传
            CommonPdfAndWordResult wordPdfResult = word2PdfAndUpload(osList, fileName, "");
            result.setPdfAndWordResult(wordPdfResult);
            result.setCreateFlag(true);
            popularPdfGenerateResultBridgeMap(result, pdfResultList);
            ThreadLocalUtil.clearUserId();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 允许可以在统一处理结果
     *
     * @param pdfResult pdf结果
     */
    protected void getPdfGenerateResultAfter(ResultOfPdfGenerator pdfResult, BasePdfGenerator generator) {

    }

    //--------------------------------------------------------------------------------
    //  一些私有的方法
    //--------------------------------------------------------------------------------
    protected abstract void customerPopularPdfGenerateParam(PdfGenerateParam pdfGenerateParam);

    protected abstract void customerPopularPdfGenerateParam(PdfGenerateParam pdfGenerateParam, Map<String, Object> customerBusinessDataMap);

    protected abstract List<BasePdfGenerator> getPdfGenerator(PdfGenerateParam pdfGenerateParam);

    protected abstract String getDownloadFileName(PdfGenerateParam pdfGenerateParam);

    protected abstract void popularPdfGenerateResultBridgeMap(GeneratorPdfWordResult result, List<ResultOfPdfGenerator> pdfResultList);

    protected abstract AbstractCustomerPdfCreateField getCustomerPdfField(String jasonStr);
}
